{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<torch._C.Generator at 0x7f316f0ec5f0>"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "%matplotlib inline\n",
    "# import some dependencies\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "try:\n",
    "    import seaborn as sns\n",
    "    sns.set()\n",
    "except ImportError:\n",
    "    pass\n",
    "\n",
    "import torch\n",
    "from torch.autograd import Variable\n",
    "\n",
    "import pyro\n",
    "import pyro.infer\n",
    "import pyro.optim\n",
    "import pyro.distributions as dist\n",
    "\n",
    "torch.manual_seed(101)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Inference in Pyro: From Stochastic Functions to Marginal Distributions\n",
    "\n",
    "Stochastic functions induce a joint probability distribution $p(y, z \\; \\vert \\; x)$ over their latent variables $z$ and return values $y$, and this joint distribution induces a marginal distribution over return values of the function. However, for non-primitive stochastic functions, we can no longer explicitly compute the marginal probability of an output $p(y \\; \\vert \\; x)$ or draw samples from the marginal distribution over return values $y \\sim p (y \\; \\vert \\; x)$.\n",
    "\n",
    "In its most general formulation, *inference* in a universal probabilistic programming language like Pyro is the problem of constructing this marginal distribution given an arbitrary boolean constraint so that we can perform these computations. The constraint can be a deterministic function of the return value, the internal randomness, or both.\n",
    "\n",
    "*Bayesian inference* or *posterior inference* is an important special case of this more general formulation that admits tractable approximations. In Bayesian inference, the return value is always the values of some subset internal `sample` statements, and the constraint is an equality constraint on the other internal `sample` statements.  Much of modern machine learning can be cast as approximate Bayesian inference and expressed succinctly in a language like Pyro.\n",
    "\n",
    "To motivate the rest of this tutorial, let's first build a generative model for a simple physical problem so that we can use Pyro's inference machinery to solve it."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## A Simple Example\n",
    "\n",
    "Suppose we are trying to figure out how much something weighs, but the scale we're using is unreliable and gives slightly different answers every time we weigh the same object.  We could try to compensate for this variability by integrating the noisy measurement information with a guess based on some prior knowledge about the object, like its density or material properties.  The following model encodes this process:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def scale(guess):\n",
    "    # The prior over weight encodes our uncertainty about our guess\n",
    "    weight = pyro.sample(\"weight\", dist.normal, guess, Variable(torch.ones(1)))\n",
    "    # This encodes our belief about the noisiness of the scale:\n",
    "    # the measurement fluctuates around the true weight\n",
    "    return pyro.sample(\"measurement\", dist.normal, weight, Variable(torch.Tensor([0.75])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Representing Marginal Distributions\n",
    "\n",
    "Before we actually try using our model to estimate an object's weight, let's try analyzing our model's behavior.  In particular, we can use importance sampling to simulate the marginal distribution of measurement values we'd expect to see a priori for a given guess.\n",
    "\n",
    "Marginalization in Pyro with `pyro.infer.Marginal` is split into two steps. First, we collect a number of weighted execution traces of the model. Then, we can collapse those traces into a histogram over possible return values given a particular set of arguments.\n",
    "\n",
    "Collecting execution traces can be done either through sampling or, for models with only discrete latent variables, exact enumeration.  To create a basic importance sampler over execution traces (using the prior as the proposal distribution), we can write:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "posterior = pyro.infer.Importance(scale, num_samples=100)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`posterior` is not a particularly useful object on its own, though advanced users can call it with arguments for `scale` to sample a raw execution trace.  Instead, `posterior` is meant to be consumed by `pyro.infer.Marginal`, which creates a primitive stochastic function with the same input and output types as `scale`.  "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Variable containing:\n",
      " 7.9588\n",
      "[torch.FloatTensor of size 1]\n",
      "\n"
     ]
    }
   ],
   "source": [
    "guess = Variable(torch.Tensor([8.5]))\n",
    "\n",
    "marginal = pyro.infer.Marginal(posterior)\n",
    "print(marginal(guess))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "When called with an input `guess`, `marginal` first uses `posterior` to generate a sequence of weighted execution traces given `guess`, then builds a histogram over return values from the traces, and finally returns a sample drawn from the histogram.  Calling `marginal` with the same arguments more than once will sample from the same histogram."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f3160ed6da0>"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f31a33016d8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist([marginal(guess).data[0] for _ in range(100)], range=(5.0, 12.0))\n",
    "plt.title(\"P(measurement | guess)\")\n",
    "plt.xlabel(\"weight\")\n",
    "plt.ylabel(\"#\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`pyro.infer.Marginal` also accepts the optional keyword argument `sites=[name1, name2, ...]` that provides a list of names of latent variables.  When `sites` is specified, `marginal` will return a dictionary where the keys are the names in `sites` and the values are values at those sites from a single execution trace.  This is useful because we may wish to compute many different marginals from the same posterior object."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Conditioning Models on Data\n",
    "\n",
    "The real utility of probabilistic programming is in the ability to condition generative models on observed data and infer the latent factors that might have produced that data. In Pyro, we separate the expression of conditioning from its evaluation via inference, making it possible to write a model once and condition it on many different observations.  Pyro supports constraining a model's internal `sample` statements to be equal to a given set of observations.\n",
    "\n",
    "Consider `scale` once again.  Suppose we want to sample from the marginal distribution of `weight` given input `guess = 0.5`, but now we have observed that `measurement == 0.1`.  Pyro provides the function `pyro.condition` to allow us to constrain the values of sample statements.  `pyro.condition` is a higher-order function that takes a model and a dictionary of data and returns a new model that has the same input and output signatures but always uses the given values at observed `sample` statements:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "conditioned_scale = pyro.condition(\n",
    "    scale, data={\"measurement\": Variable(torch.Tensor([8.5]))})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Because it behaves just like an ordinary Python function, conditioning can be deferred or parametrized with Python's `lambda` or `def`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def deferred_conditioned_scale(measurement, *args, **kwargs):\n",
    "    return pyro.condition(scale, data={\"measurement\": measurement})(*args, **kwargs)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In some cases it might be more convenient to pass observations directly to individual `pyro.sample` statements instead of using `pyro.condition`.  The optional `obs` keyword argument is reserved by `pyro.sample` for that purpose; in addition, `pyro.observe` is an alias for `pyro.sample` with `obs`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "# equivalent to pyro.condition(scale, data={\"measurement\": Variable(torch.ones(1))})\n",
    "def scale_obs(guess):\n",
    "    z = pyro.sample(\"weight\", dist.normal, guess, Variable(torch.ones(1)))\n",
    "     # here we attach an observation measurement == 1\n",
    "    return pyro.sample(\"measurement\", dist.normal, weight, Variable(torch.ones(1)), \n",
    "                       obs=Variable(torch.Tensor([0.1])))\n",
    "\n",
    "# equivalent to scale_obs:\n",
    "def scale_obs(guess):\n",
    "    z = pyro.sample(\"weight\", dist.normal, guess, Variable(torch.ones(1)))\n",
    "    # here we attach an observation measurement == 1\n",
    "    return pyro.observe(\"measurement\", dist.normal, Variable(torch.ones(1)), \n",
    "                        weight, Variable(torch.Tensor([0.1])))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, hardcoding is not usually recommended due to its invasive non-compositional nature.  By contrast, using `pyro.condition`, conditioning may be composed freely to form multiple complex queries on probabilistic models without modifying the underlying model.  The only restriction is that a single site may only be constrained once."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def scale2(guess):\n",
    "    weight = pyro.sample(\"weight\", dist.normal, \n",
    "                         guess, Variable(torch.ones(1)))\n",
    "    tolerance = torch.abs(\n",
    "        pyro.sample(\"tolerance\", dist.normal, Variable(torch.zeros(1)), Variable(torch.ones(1))))\n",
    "    \n",
    "    return pyro.sample(\"measurement\", dist.normal, weight, tolerance)\n",
    "\n",
    "# conditioning composes: \n",
    "# the following are all equivalent and do not interfere with each other\n",
    "conditioned_scale2_1 = pyro.condition(\n",
    "    pyro.condition(scale2, data={\"weight\": Variable(torch.ones(1))}), \n",
    "    data={\"measurement\": Variable(torch.ones(1))})\n",
    "\n",
    "conditioned_scale2_2 = pyro.condition(\n",
    "    pyro.condition(scale2, data={\"measurement\": Variable(torch.ones(1))}), \n",
    "    data={\"weight\": Variable(torch.ones(1))})\n",
    "\n",
    "conditioned_scale2_3 = pyro.condition(\n",
    "    scale2, data={\"weight\": Variable(torch.ones(1)), \"measurement\": Variable(torch.ones(1))})"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In addition to `pyro.condition` for incorporating observations, Pyro also contains `pyro.do`, an implementation of Pearl's `do`-operator used for causal inference with an identical interface to `pyro.condition`.  `condition` and `do` can be mixed and composed freely, making Pyro a powerful tool for model-based causal inference.  See the [causal inference tutorial](http://pyro.ai/examples/causal_inference.html) for more details about `pyro.do` and a simple example of causal inference in a model of disease diagnosis."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Flexible Approximate Inference With Guide Functions\n",
    "\n",
    "Let's return to `deferred_conditioned_scale`.  Now that we have constrained `measurement` against some data, we can use Pyro's approximate inference algorithms to estimate the distribution over `weight` given `guess` and `measurement == data`.  We saw earlier how to use importance sampling to do this for `scale`; we can use exactly the same constructs with a conditioned model:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "{'weight': Variable containing:\n",
      " 8.3751\n",
      "[torch.FloatTensor of size 1]\n",
      "}\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f3160df96d8>"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nWPxERJL5f4xv2j3SpzWRAAAAAElFTkSuQmCC\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3160ea80b8>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "guess = Variable(torch.Tensor([8.5]))\n",
    "measurement = Variable(torch.Tensor([9.5]))\n",
    "\n",
    "conditioned_scale = pyro.condition(scale, data={\"measurement\": measurement})\n",
    "\n",
    "marginal = pyro.infer.Marginal(\n",
    "    pyro.infer.Importance(conditioned_scale, num_samples=100), sites=[\"weight\"])\n",
    "\n",
    "# The marginal distribution concentrates around the data\n",
    "print(marginal(guess))\n",
    "plt.hist([marginal(guess)[\"weight\"].data[0] for _ in range(100)], range=(5.0, 12.0))\n",
    "plt.title(\"P(weight | measurement, guess)\")\n",
    "plt.xlabel(\"weight\")\n",
    "plt.ylabel(\"#\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "However, this approach is extremely computationally inefficient because the prior distribution over `weight` may be very far from the true distribution over weights, especially if our initial `guess` is not very good.\n",
    "\n",
    "Therefore, some inference algorithms in Pyro, like `pyro.infer.Importance` and `pyro.infer.SVI`, allow us to use arbitrary stochastic functions, which we will call *guide functions* or *guides*, as approximate posterior distributions.  Guide functions must satisfy these two criteria to be valid approximations for a particular model: \n",
    "1. all unobserved sample statements that appear in the model appear in the guide.\n",
    "2. the guide has the same input signature as the model (i.e. takes the same arguments)\n",
    "\n",
    "Guide functions can serve as programmable, data-dependent proposal distributions for importance sampling, rejection sampling, sequential Monte Carlo, MCMC, and independent Metropolis-Hastings, and as variational distributions or inference networks for stochastic variational inference.  Currently, only importance sampling and stochastic variational inference are implemented in Pyro, but we plan to add other algorithms in the future.\n",
    "\n",
    "Although the precise meaning of the guide is different across different inference algorithms, the guide function should generally be chosen so that it closely approximates the distribution over all unobserved `sample` statements in the model.  The simplest guide for `deferred_conditioned_scale` matches the prior distribution over `weight`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def scale_prior_guide(guess):\n",
    "    return pyro.sample(\"weight\", dist.normal, guess, Variable(torch.ones(1)))\n",
    "\n",
    "posterior = pyro.infer.Importance(conditioned_scale, \n",
    "                                  guide=scale_prior_guide,\n",
    "                                  num_samples=10)\n",
    "\n",
    "marginal = pyro.infer.Marginal(posterior, sites=[\"weight\"])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Can we do better than the prior?  In the case of `scale`, it turns out that the true posterior distribution over `weight` given `guess` and `measurement` can be written directly as:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f3160cdd710>"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3160e57d68>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "def scale_posterior_guide(measurement, guess):\n",
    "    # note that torch.size(measurement, 0) is the total number of measurements\n",
    "    # that we're conditioning on\n",
    "    a = (guess + torch.sum(measurement)) / (measurement.size(0) + 1.0)\n",
    "    b = Variable(torch.ones(1)) / (measurement.size(0) + 1.0)\n",
    "    return pyro.sample(\"weight\", dist.normal, a, b)\n",
    "\n",
    "posterior = pyro.infer.Importance(deferred_conditioned_scale,\n",
    "                                  guide=scale_posterior_guide,\n",
    "                                  num_samples=20)\n",
    "\n",
    "marginal = pyro.infer.Marginal(posterior, sites=[\"weight\"])\n",
    "plt.hist([marginal(measurement, guess)[\"weight\"].data[0] for _ in range(100)], range=(5.0, 12.0))\n",
    "plt.title(\"P(weight | measurement, guess)\")\n",
    "plt.xlabel(\"weight\")\n",
    "plt.ylabel(\"#\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Parametrized Stochastic Functions and Variational Inference\n",
    "\n",
    "Although we could write out the exact posterior distribution for `scale`, in general it is intractable to specify a guide that is a good approximation to the posterior distribution of an arbitrary conditioned stochastic function.  What we can do instead is use the top-level function `pyro.param` to specify a *family* of guides indexed by named parameters, and search for the member of that family that is the best approximation.  This approach to approximate posterior inference is called *variational inference*.\n",
    "\n",
    "`pyro.param` is a frontend for Pyro's key-value *parameter store*, which is described in more detail in the documentation. Like `pyro.sample`, `pyro.param` is always called with a name as its first argument.  The first time `pyro.param` is called with a particular name, it stores its argument in the parameter store and then returns that value.  After that, when it is called with that name, it returns the value from the parameter store regardless of any other arguments.  It is similar to `simple_param_store.setdefault` here, but with some additional tracking and management functionality.\n",
    "\n",
    "```python\n",
    "simple_param_store = {}\n",
    "a = simple_param_store.setdefault(\"a\", torch.randn(1))\n",
    "```\n",
    "\n",
    "For example, we can parametrize `a` and `b` in `scale_posterior_guide` instead of specifying them by hand:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "def scale_parametrized_guide(guess):\n",
    "    a = pyro.param(\"a\", Variable(torch.randn(1) + guess.data.clone(), requires_grad=True))\n",
    "    b = pyro.param(\"b\", Variable(torch.randn(1), requires_grad=True))\n",
    "    return pyro.sample(\"weight\", dist.normal, a, torch.abs(b))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pyro is built to enable *stochastic variational inference*, a powerful and widely applicable class of variational inference algorithms with three key characteristics: \n",
    "1. Parameters are always real-valued tensors\n",
    "2. We compute Monte Carlo estimates of a loss function from samples of execution histories of the model and guide\n",
    "3. We use stochastic gradient descent to search for the optimal parameters.  \n",
    "\n",
    "Combining stochastic gradient descent with PyTorch's GPU-accelerated tensor math and automatic differentiation allows us to scale variational inference to very high-dimensional parameter spaces and massive datasets.  \n",
    "\n",
    "Pyro's SVI functionality is described in detail in the [SVI tutorial](http://pyro.ai/examples/svi_part_i.html). Here is a very simple example applying it to `scale`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f316037f198>"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAEWCAYAAABv+EDhAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl8E3XeB/BPjt5pS+8CLaUttIWWUqDcd2u5Csj5uIig\niKKuioKIoi6uFysqHni7j6zH4y6uqwsqeBYREKEgIPdNhSo9oHfplWSeP9Kkk2QmmUknnTTzfb9e\nviSTOX6TJr/v/G4VwzAMCCGEKI5a7gQQQgiRBwUAQghRKAoAhBCiUBQACCFEoSgAEEKIQlEAIIQQ\nhaIAQAghCqWVOwGEeJKcnBxcuXIFGo3Gsm3mzJnIyMjAJ598gn/96192xyxYsACHDh2CVquFWq1G\nWloaVq9ejdTUVMs+Z8+exQsvvIB9+/bBaDQiIyMDy5Ytw8CBAzvkvgjhQiUAQmy89dZbOHjwoOW/\n1atXOz1m9erVOHjwIAoLCzFkyBCsXLnS8t7Fixcxb948pKamoqCgADt37kReXh4WL16MgwcPuvNW\nCHGIAgAhEtJoNMjPz8e5c+cs21599VVkZWVh2bJl6NKlC3Q6HRYuXIjp06fjhRdekDG1ROkoABAi\noebmZnzxxRfo37+/Zdvu3bsxadIku30nT56MAwcOoLGxsSOTSIgFtQEQYuPuu++2agNYuXIltFrH\nP5Wnn34aa9euRWNjI/z8/PDaa69Z3qusrERUVJTdMVFRUTAajaiuroa/v790N0CIQBQACLHx+uuv\nY8SIEVbbPvvsM4fHPPbYY5g7dy6MRiMOHDiAu+66Cx9++CHS0tIQFhaG8vJyu2PKy8uhVqsREhIi\nafoJEYqqgAiRkFqtRnZ2Nnr06IGffvoJADB8+HB8/fXXdvt+9dVXyMrKQkBAQEcnkxAAFAAIEYxh\nGDQ1NVn9x+XgwYM4d+4cevXqBQC45557cPDgQbz00kuoqqpCXV0dPvzwQ2zevBkrVqzoyFsgxIqK\n1gMgpA3XOIARI0YgNzcXq1atstv/2LFjWLRokWUcAABERkZi/vz5uOWWWyz7nT59GuvWrcO+ffvA\nMAwyMjJw3333ITs72+33RAgfCgCEEKJQVAVECCEKRQGAEEIUigIAIYQoFAUAQghRqE41EKy8vNbl\nY8PCAlFZeU3C1Hg+umdloHtWhvbcc1RUMOd2xZQAtFqN8528DN2zMtA9K4M77lkxAYAQQog1CgCE\nEKJQFAAIIUShZA8ABoMBM2bMwB133CF3UgghRFFkDwAffPABkpOT5U4GIYQojqwBoKSkBNu3b8ec\nOXPkTAYhhCiSrOMA1qxZgwcffBD19fWC9g8LC2xXVyi+vrDejO5ZGeielUHqe5YtAPzwww8IDw9H\nRkYG9u7dK+iY9gz8iIoKtgwkO1ZUgZKr15A7KE7w8XUNLfDRquHn03n6H7PvWSnonpWB7ln8sVxk\nCwAHDhzAtm3bsGPHDjQ1NaGurg4rVqzACy+84PZrr9t4CAAwfmB3qFUqQccsfWUntBoV3nlwvDuT\nRgghHUa2APDAAw/ggQceAADs3bsXGzZs6JDM3woDQFj+DwDQG2jpBEKI95C9F5CcjLQWDiFEwTxi\nMrihQ4di6NChHX5dyv8JIUrmEQGgoxw6ewXfFl60vKbVMAkhSqaoALD+P4etXlMVECFEyRTdBkD5\nPyFEyRQeACgCEEKUS9EBwEj5PyFEwRQdAKgEQAhRMoUHALlTQAgh8lF4AKAIQAhRLkUHAGoDIIQo\nmaIDAJUACCFKpvAAIHcKCCFEPgoPAMIiAJUUCCHeSNEBwChwP8r+CSHeSNEBgBHaCuxkt+q6Jry1\n+ShK27FiGSGEdDRFBwCpJoP79MfzKDxRhnc+PybJ+QghpCMoOgAIzf8ZJ0WAFoOpMulao769SSKE\nkA6j8AAgtBHY8fvmdYUNNLCAENKJKDwAuHKM/UHq1k+R1hcghHQmig4AQjNs9m5cR5hLAEYqARBC\nOhFFBwDhD+xtO3Jl8mp1awCg/J8Q0okoaklIW84adwGgvrEF+0+WtR3DcYglAFAEIIR0IsoOAALy\n67c3H8PRCxWW13qDESoVoNW0FZ40VAVECOmEFF0FJKQN4Mzv1VavH3rrZyx5frvVNnMJwECNwISQ\nTkTRAcCV/LquocVumzkACB5ZTAghHkDRAUCqKhuNmsYBEEI6H0UHAKlm+VRRGwAhpBNSeACQ5jzm\nEgBl/4SQzkThAcCUZbfojXj9v0dwoqjCyRHcWvN/QgjpVBQdAMzrARw4XY5fTpXj+Y2H7HcS8Fiv\npghACOmEFB0AzCWA9tbdUwAghHRGsg0Ea2pqwvz589Hc3AyDwYCJEydi6dKlHZoGcxsAe0RwacU1\nxIQHijqPChQACCGdj2wlAF9fX7z//vv4/PPPsWnTJuzcuROHDnFUwbgRVy+gdR93bBoIIUQusgUA\nlUqFoKAgAIBer4der7d0p+wo5pofdhyoqGkSfZ5jLjYeE0KInGSdC8hgMGDWrFm4ePEibrzxRvTv\n39/h/mFhgdBqNZJdPzjYH1FRwQgJqbRsY8AgKirY8povJrH3OcaaK4i93RN4Wno6At2zMtA9t5+s\nAUCj0WDz5s2oqanB3XffjdOnTyMlJYV3/8p2LLrO9cHVVDegvLwWNTWNlm0MA5SX11q95lJWVsNZ\nYmEfK8Yrn/wKjUaNe2b1c+l4LlFRwS6np7Oie1YGumfxx3LxiNlAQ0JCMHToUOzcudNhAGiPxib7\n9Xod9f0pPFGKbb8Uo0Vv5HyfASRt+v313FUJz0YIIc7J1gZQUVGBmpoaAEBjYyN2796NpKQkt11v\n95E/7LYxHG0AZm9tPobTxdW8M4ZKNY0EIYTIRbYSQFlZGR5++GEYDAYwDINJkyZh/PjxsqRFyMIw\ndsdQ/k8I6eRkCwBpaWnYtGmTXJdvxVj9T9SRPMec/6MGe46V4E+5vWmAGCHEo3lEG4Bc2vMUz1cF\n9PQH+wEA/ZIj0C8pwvULEEKImyloKghpn8adxQ6+xmNCCPEUCgoA/FwpCDhrBKbKH0KIp1NMAOAa\n0NWedlxn1UdiRjVTjyJCiByUEwA4trUn43V6qEr4NYQsTk8IIVJTTADg8skPZ2EwGl0MBM6rgEor\nr2Hx2h/wbeFF7D9ZBr2Bu13A6Obmguq6JvxWoqxRk4QQ5xTdC+hqTRP2Hi91qSqouLweKfFdeN/f\ntOuCJdPduO0sAGDGqERMH5Vot6+71xJe9tpPAIB3HhwHrUbRMZ8QwqKc3ICnTt7V2pdnPzrg8H2u\nJ+4zxVWc+xo6aDF5g4GqmgghbRQTAPiaZP18NB22mntji4FzO7sN4FhRBcraMekdIYQIpZgAwKcj\n++s3NXMHAHYJYN3GQ3j47T0dlSRCiIIpJgDw9cps0hs6qgCA4vJ6zu3ubgMghBAuigkAfJp5nso7\nksHd3YBaUXdTQgib4gNAk94o+9SezgoAJRXXaGoJQojkFBMAVDzNwM08DbMdyVEVUHFZHR55Zw9e\n++xIu69DI44JIWyKCQB83YCMjCurAUjLUTfQ4vI6AMCR8+1fMUzu+ySEeBblBAA+jHumhRbDUQnA\nlTUF6hpa0KK3L9lQAYAQwqaYkcB8vYA6OlNkGMZuojiuAPDz0RL8/cvjLl1j6Ss7ERrki/97crLd\ntdmKy+sQGx5Io4MJUSjF//KNDIOPvjvt0rEGoxEbtpwQdcybm4/ZzQnEVQklJPO/WFqLYxcq8FtJ\nrWXwmDmYVNc32+3PvsqxCxVY/W4h/rFVXPoJId5DOSUAnkaA31vr2F1x5FwFfjpaIuqY/SfLMCQt\nGtlp0ZZtYkohlbVNCA70gVajxl//sc/qvSF9olFa2cB7LPs6Z3+vBgD8fKwUt09LF54AQojXUEwA\n4GsEPlZUabft5G/227jwze7pTEOz3uq10P75FTWNWPHGbsRH6xAZ6m/3fuGJMscnYF2HegQRQpQT\nAER47+uTbj2/3qZPv9C8+I8rppHEl8rqcKlMfMmFfRnzNWnlMkKUS/FtAFxqOOrPpWQ7qKujnsbZ\nlzG3O4hZuYwQ4l0UEwDEZHONAqeHqG1ocSktzS6WANobJhirKiDT/92d/18qq8OVKv52CUKIfBQT\nANzhw29OuXScqyWA9pYU2Ieb2x1UKtO4gT3HSwTNSSS23ePxDYVY+dbPoo4hhHQMxQQAT6rpaLHJ\nRIVOBqpv54Iuv5WyFqmxlABU+HbfRbzz+XF88sM5h8fX1DdjyfPb8dG3wrrNdtQkd4QQ1ygiANRc\na8ZGF/v6u0NLixGXr9Zb5iES+mTfzDG6V4zXPjuC9746AaORsZQGWvRG7Dx8GQBw+lLbimWf/ngO\n3+27ZHV8UesqZwUHigVdT2hVGiFEHooIAB9+fQrnW/u9e4Lfr9Th0b/vxYsfHwIgvA2gpaX9T9Q7\nfr2MY0UVVl1Pq+tMjd7mBmEjw2DLz7/hXwVn2nWtxiYKAIR4MkUEgHIPa4Q0LwxzutgUlISWAPYc\nL5Xk+uwSgDXTxrprfI3b9gcdu1CBY0UVnHvbjncghHgWRQQAT2Ob4QttAzghcIAa33XM1GoV5/QT\nFy7XouCXYlTVNQm+xrqPD2HdxkOc71EJgBDPJlsAuHz5MhYsWIApU6YgPz8f77//vtuu5WljXm2n\nf3bXOAC9geEc06BWqXirnT767jTqXezeaquxhUoAhHgy2UYCazQaPPzww0hPT0ddXR1mz56NkSNH\nolevXnIlqcPYNo66axzY6YuVePj1XXbbj12owI+Hfuc9znacgqv0ek8LvYQQNtlKANHR0UhPN01C\nptPpkJSUhNJSaeq4Oxt3lQCOnrvCuf3rwosOu5TyBQCxyRQzZmBjwRn8d8d5cRcghLSLR8wFVFxc\njBMnTqB///4O9wsLC4RWqxF9fq3Wc5s6oqKCEVxS63xHFwQH+bp03B8VbY3mUVHBln+HtjZe224H\ngMhInd20EgEXq3j3t/Vta5fTJbMdfweEcHYtb0T3rAxS37PsAaC+vh5Lly7FI488Ap1O53DfytY5\n78WSovuku5SX16LKTb2UXJ2tdPOOtgFh5eVtwam6uoFzOwCUlNbgm8KLqGtowQ05vQEAFay/l+3+\nfITuxycqKrjd5+hs6J6VoT33zBc4ZH00bmlpwdKlSzFt2jRMmDBBzqTI5sj5q25rpG5oan8j7OK1\n23Dhco3d9lXv7MHlq20lgha9EZ/+eB7fFF7Chcs12H7od6sAZK7m0huMaGppawPRG4w4U9xWUiCE\ndBzZAgDDMHj00UeRlJSERYsWyZUM2b3071/d1gbQ0Nj+AMAwwNY9v9ltL624hkf/vtfymp3ZP/X+\nfnzw9SlU1rX1QDIyDOobW7Bu4yHcte5HHDpzBYfOXsF/d5zH3/7vAOe1D5+7ii93F7X7Hggh3GSr\nAvrll1+wefNmpKSk4PrrrwcALF++HGPHjpUrSbIRuiCMWNckKAEAELRmMFejchOrt1NRSS2e+eAX\ny+v1nx4GAHSPDOI958uf/AoAGN2/G0JdbM8ghPCTLQBkZ2fj1CnXZtMUz7O7I7qrG+iRs9y9gMTS\nalQwMgze3HSUdx/bCe4A4Lv9bXMJHTl3lfM4jca64bimvhkhNpl9dV0TQoN8wTAMvt57EZm9IhEb\nHoCGJgN0AT5iboUQwiJ7IzBxXzfQYhdWDePio1GjorrR4fgA2ymubTXzNMTbli7uf3UXFk1Jw+jM\nbpZtVXVN6BETjDPF1fhk+zl8sv0corsEoKyqAWOzuuHmSWkwGI3QqD23t5cnMhoZqNUeNE0u6XD0\ni/EA/9nueBpmuWk1anz5s307ANs5J5PtfV14kffctn46UmL1uqHJgKvVjTjMKkWUtfac+vHQH3j3\ny+O4/bntVlVOZu99dRJf772IbQeKrRqtle4/28/htud+EDzth8FoxLqNB/HXfxSizMXeeMTzUAnA\nA1TVuXcJyvbSatT4/hfHU0C/95Vr6yhXc0xVcfpSFSpqGi2v9QYjVr65m7ci76ejpoBxtaYRcd2t\nz73j1z+s9p09Ngndo3TI6hXpUnq9hblh/2xxNbLTonHhcg3iooLgwzPO5mJpHY4VmeaieuK9fXh9\nmfLa6ryRIkoAnt0C4Pm0WvdVE5RWcD9NfrW3rcRgMHJNXWfPdtGf4nL7KrBPfzyP9f85jMpa4RPe\nebujF67iqff34+9fHOd8v/BEKdZ+1NZTq0GCSf5OXazEhi0naNEgmSkiAJD2kaNu/TBrGgtn7Qt8\nHM1G+sDrP6G+scXS/lJV14R1Gw/it5Ja1De24Pv9l1BzzbNLZlL5rXUk+v5T5Zzvv7X5mOD5oYxG\nBqcuVjodhLj2nwex68hlHC/inuHW1UGMRByqAiJOydFMWF7VVgUkdHZS27b05hbHT6r3vrwTs8Yk\nYeqInlj70QGUVjbg2Hv7LO//8/sziIsyjU6fOToRpZWmRmcfrRq/nr2CjKQI+PmIn5pEjKKSGny3\n7xIWTkqzXKuuoQUVNY3oEWMa3Xn2UhVampoRGRog6bUZhrFbFc6Z7/ZfwsfbzmLKsATMGZfsdH+u\njH5jwRl8u+8SXrxnJLro/ERdn4hDAYA4JXcVmrP2B7PCE6Xo3yfW8rpJwBKan+04j6AAH5RWck/H\nYa5GevWzIwCAsspr0GjUKPilGMGBPugRrcPIzK4Y1jfW7tjv9l/Ct4UXMWFwD1yXHYczxdXw99Wg\nvlGP7/ZdwoKJqQgL9oPeYMTV6kZoNWpEhPpbneOp9/eDYYDK2ibcN7c//Hw0eO6fB1BcXo+1dw5H\nZKg/lr38IwBgw8M5uFLdgDc3HcOiKWmW4OUMXye085drsHHbWc73Pv3xHPKy43H5aj0KT5Rhfl4K\n1GoVTrXO/3TsQoWgAGBmZBioW+vwzPNCnfu9BoNSowSfg4injAAgdw7WyTEMA1+tWrJposUyClwx\n5/OfinDbzEzL6yqB9fwffiN8PMr2Q22NyrXXWnCsqBLHiipx+co1fLG7CAsnpmLcAFNL9L++Ny2p\n+a+CM/Dz1dg1lBeX12HC4Hj88/u2pTdzB8Wh8EQpmpoNuGN6uiVzPnmxCu9uOYE/z8iwrChXXF5n\nN0Dug29O4cLlGqx+txDpPcNw14wMBPq7NlZC7+DvveXn31BW2YB9J8sAAL+V1uK+OZm8+1fUNMLI\nMJyllD+u1OOx/92LmyelYmxWWyv+6/89gr8tGYaY8ECX0k+cozYA4hTDcA/0MtO4uS+5mBHNRsY0\nmOzA6XJ8/lOR+xJl44vWKSs+aA0mtl0luXpJXalutMr8AaDgl2LUXmtBs96Id7ecsHrvwKlyq8br\n6rpmq6D8/tcncfR82/Kcx4oq8eMh615QYjibRdec+QPA+T9qONeQbtEbUVXXhBVv7MbKN38GANQ3\ntli9b+6pZftZAMC7W0/YbSPSUUYJoANEhPjhao139iwx8K4hbOLro5akZ4gUjEYGD7z+k92qax3p\n9KUqPPsR9/xGYgT6a62Cn5Ex3ZtZTX2z1dgHZ5n9T0cuY/uh37Fy3kDLtne3nsDU4Qmc+4tdGa68\nsgHBga0lktZngiff24ffr7SNv2huMeDel3daXr+1+Zjl34H+WquJAgFTN1XiPhQAiFPOeuGobftf\nyshgNMqa+QOQJPMHgAA/xz/PTbsuYNOuCw73UatVKDxRij+u1FtKRGdZg/ZsB8/tO1mGwWnRAICX\nPzksKr2NzQYEt9bW/FZSizX/94tV5g8A5Q6mPg/002Llm7vtth84XY79J8uwaEof+NiUSowMAzDA\nlZpGbNp5Ho1NBkwZnoAWvRERof6I7hIAhmFw4XItvtrzGzKSwjG0bwwultYhVOeLmLBAnPujGt0i\nguCjVaP2Wguu1jQiOiwAlTVNCPDXIjLUHyqYGqz5xkk4c62xBWd/r0GfhC4un8MdBAWArVu3YsyY\nMdDpdHjllVdw+PBhLFu2DBkZGe5OnySU2ASwcFIqPvhamrmWHFX/eBqh7QWdwSUJpvJQq1VWT9mA\n44D+5qajuDq+F8YP7M67D5/GZoPVtCZcT+9/ebeQ9/jgAB9cvmo/LuS11gb4kCBfZCZHoG/PcBw8\nVYZ1H/2C6vpmRHcJwLD0GOw5ZlpR8FDrHFhajQpP3z4Mx4sqLL+FX06X4/12/C76JIShsrYJDc16\ndA0PREp8FzS1GJDaIwxxUUGWABoR4o/SygaUVV5Dao8wbN5VZDU31l0zMjAwJRJ1DXr8caUeb20+\niukjE5E7KA71jS0I8vfB8aIK1FxrxqCUaLvAJxUVI2AimmnTpuGLL77A4cOH8dRTT2HhwoX46KOP\nsHHjRrckio+riyE89r978ccV8dMAqFUqwTN1RoT44ypr9Krc1t45HA+99XOHXEsX4IM6iRaSb69/\nPTUZ8/7yldzJ8BgJMcH4rdT6dzMqsyt2Hb5seR3op7VrZ+mXFIEj57kn8HOkf3IEfuWZ+I+4LjzE\nD0/fORL+LsaBdi0Io9WaCgo//fQT5s6di2nTpqGpyTvru9k689xivh24DKaQNuDs1moFd3tn05EO\nuY6cpo3oidyBcYL2tc38AVhl/gB3I7srmT8AyvzdpKKmCRf+kL49RFAuoVKpsHXrVmzduhXDhw8H\nYFrNy9uJqduWqhpcqvp0XxcHKAX4iT/Odi1gW2+vGIs7r093KT1i/SBwzACfqSO4G0TbY2CKtH3Z\nR/aLRY9YYX38O7sBvSPRKy5U7mRIomtEIMKCXR/YFhvBv3aGqwQFgMceewxffvkl5syZg/j4eBQV\nFWHo0KGSJ8ZdXJ1uWY6pcqW6pqt1hq4EIGeH+Gg1HtVQ7EjvuC4O3+8eJf5H2C8p3NXkcPLRatxW\nJ+xIj+iODzr3zs7EIzcNctv5pQ7Ojjh7KBuWHgPA9B1jB4pukUHITI5AYjfpA6Ggb9HAgQPxxhtv\n4OabbwYA9OzZE3/5y18kT4ynkSPTkqraSatR8wYTP18NHvxTFud7tt3whHBWAnCXxK7c9Zrt4exZ\nIchJzxwuUmfWvj5q+AhYpU1qK+YNQLbNyNyJQ+IlvUZUF3/O7a6UTIVwtCIdnyD/tu9ASnzbA0NO\na8N5ZnIE53F+WrXDnl1LpqVjw8M5eGrxUASzFjr666LBuH9uf7cEfUFnfPbZZ1FbWwu9Xo8bb7wR\nWVlZ2Lx5s+SJ8TRSPY3fNCEFd88U1mPKwLG0oqvWLx/HuV0FICE2hPM9rqUdnZFrTZFZY4RPNSBU\nTydBxddXXEbkaIplAHj8lsF47f4xos7pq1U7XabTHXMU6QJ8cP2oRKtt0V2knX9o8lDuKrgH5w2Q\n5PxpPaxLeAF+WlFB7JWlo/Dq/WMQEmjKoNnBYH5eCv48I4O3utPXR4N7Z/UTNb1F/+QIQUuyukrQ\nmXfv3o3g4GDs2rULMTEx+Oabb7Bhwwa3JcpTiMnYHD0E5wyMQ2qPMEHnkbIPe0JX7kwecF5tI+ah\nXmgJYMGEFNw2tQ/v+3fNENetWKuRNvLMGpOEkEDHaw8LffKePrIn/jwjAyv+NMBhOhNigxHor8XM\nMUmC06nVqO2eBoent81FFBcVhDvc1OYSajM5m6od0b9fkulJmb2s56jMrvjbkmF2+/aMDUFwoPAp\nLfokcP/eosOsA5aPVs07id4by+0Dc7DN94MdaFUqFbLTouHvy/2U7+ejQUx4IO6e2c+yLb0nT77Q\nQQ9VokLLvn37kJeXh5iYGNmK/R2pPV9uu3N14MflrOpKpeJPj3kQ0Lgs4f3Ahd7b+IFxGJHRlfd9\n9tzwGTb15lwLuAiZplpMo66QEp9GYACICPVHdlo0QoJ8BRXdh/aNEXRewJTR2D4VmoOMLsAHf100\nxGHQcTZ1h6O6fvYTL8C/1KcQyd1DsOHhHLyydJRlm1ajRhDPOs9CS8czxyThnlltmez8vBTLv23/\nfr5aNW/1El9Gbr2PBqnxXXi/Z8/eOdwyl5Ht+tcA94p4AKDqoAgg6NscERGBxx9/HF999RVGjhwJ\nvV4Pg8Ezhv67k5Rz3HRkuHT+ZKzi/YJdlx2H15eNscuAHZ6NIwJMHtpD8PFm7B94sE0mwFVMFxJ4\npG7H8RFY6mB/d/hKDevvG235t1bgd83cCM0OKuMGxlmup1aZApmYNRweWWDdyOooYKlUKqvMtVHE\nPE0LJqRYvTZ/b2y/P4E89eQGAZ05Zo5OxNThCVZ17XGshnvb37SPj+N6+R4xpmDo56uxCiQWKhUe\nmj+QtzoyTOdnaVji+p24s3pHCEFXX7duHRITE/Hiiy8iNDQUJSUlWLRokbvTJjsxmUdECHfjVZuO\n690jqHTGs4tKpUKAn1ZUBmK+HrtR1tHT9N/usC/iA7bVX6bjgwN9cPfMflaNbWZyjPkV+oNlf3f4\n2gDYVR/OJl4zC2qd2ZMdVO7/0wBLadX8GTY282fM5n3Cgv0waWgPJHcLwYiMtiokZ9+xXt3beqM0\nsK4zoHckXvjzCCTEcLejDO0bY1UFM7C3danO18d0XbVahcX5fbDSpt5fyCjvYemxdt9/9ndRq7Yt\nAWgQEsRf7ffADVm4d3Y/vLl8LHIHtY29EPrd89GqLYNJ2cmaPTYJvj5q9HbSxdXd33FB37rw8HDc\ndNNNCAoKwpkzZxAbG4tZs2a5OWnyExsAnrx1CG6dwl3HLdWDqKA6aGf1+w52MW9nF1e5Ml82sQWl\nmDDu6X0NRgZpPbq0flamr76fjwaDUqO4g5rEvw4htyE4ALBLAAIyd9uMiY+51wr749Bo1Ahora4w\nT8rHt9Iiu0/9uKxu+J/xvaBSqXDL5DSr87FNHdHT6n32/ZirSXpE63Dv7EyEh/jj8UWD8dTiIZbq\nRMs9atS4dUofRIb644lbh6A7a72C1+4fjVeWtpWIRvbrijSbenyuANA1wvq7xPWbZR9nO7K/V1wo\n4iLb0mHbLTQ40BcDeovvKjp5aA+MzeoGoK1jBfu7kz+8J95cPpa/9NFBVQaC+rQdOXIES5cuha+v\nLxiGgV6vx6uvvor09I4Z3CMXsW0AcdE6nCmuclNqTHy0asDJIGwhqeYrJZh/IOwqiRtyeuGp9/dj\nfl4KPvrfWBcmAAAcB0lEQVTuNADT0PSK1tlPuc7lrLQeGeqPK9XWU2cYDEY8OG8AGAb43y3HW8/N\nfw4jw+DxWwbj421ncPIi/+euUaska1wXGgDYVQ1cVXJLpvW1Oa/zv9r/jO9lyVQiQwMQ4KfB6EzT\na3Npwvz3G9A7ElNHJGB4eixOXaqyzIUzPD0WMWEBOPt7jWXdAtv7sn3ImGXTQB3gp8XyG/ojJiwQ\nugAf6A1G5NiMTO4epcOd16dbTRmt1aiREt8Fz901wu7ehKxZ0C8pwjLPD2Cqnll9y2C8t/Ukdh0x\njW7mKnmyA4Bthmtu9L9pQgpCg/xQVdeEA6e5l8bkwvdXmzu+l+Xfhta5tGy/O45K6h1VZSzo2/zM\nM89gzZo1+Oabb/Dtt9/imWeewVNPPeXutEnGxXFgop5szROmVdVxryMrpgQwzEGDoJAMSFANEM8+\n5h8L+4eU2DUE7zw4zqoIvPbO4Q7P5Wzw3aqbBtk9vekNDFQqlenarYc7agwLDfJFQmww/pTb2+G1\nHH1mYtp5MpMjoNVa779oShrefGCs3bgKRyWAiBB/DEu3XkHMXAUUHRaAvy0ZZtdbBQAmDe1hycD8\nfDV47f4xuCHHlNHobNpM1GoVZo1JRteIILsG/Vun9MGa24fa9Wgxyx+R4LBaBAAyEiMQ1SUAAX5a\nzB6bzDnCVaVSYfUt2VZpao/bp/XF/XMzLe1TapUKapUKt+a3lbrZ1/Br7bLLblTuGhGIhFj7Kqqc\ngXEYlBrlli7NlhIA18mdXM/VvEsoQQGgoaHBMgUEAAwfPhwNDfzTunoLMV9Y87S6/VoHgdgOUhLa\nqh/gp0U3B4NTuHoS2HPeC4jtedYTmflJ2bYNwJyJ3jI5DTfk9LJ635XfTFiwn13PF3ZGafnec5z8\niVuHYMWfstp6Vzj5O/E9Xa+9czj8RfTrv25QnF2XwYSYYPj5aNCnp3WjuZA2ANv9X7t/NJ6+bShi\nwgMxZ6ypUdFRY7xKpbI8RQ7pE43M5AjeVbnum5OJpG4hGNonxuo4LpGhAXj53lGYOy4ZD93Yvv73\nPWNDMKxvDO8ALzEC/LTITI60ZIpcv0/2pqcWD8GS6X0tayeb3lc5fMAalh6LPglhWMEzUNJMTMas\n5ykBAB3X24ePoAAQEBCAvXv3Wl4XFhYiIEDaASCeSMzTYWNrAOjVPRRvLh+LSTYDWoSWACY5GZTC\nzlhslwO0XEvAddjpYa9D2xYAuM8ypn83TBxi3cOnLTNpO0bI74M9LXF6YjhGZdp3EeVKRajOF31Z\nGa6zQM3XdTOqS4Dl7yaEkWEw2iaNfNcW0gvIVqC/jyWTyE6Lxmv3j8HY/t0EHevro8H9c/ujP0d3\nWQDo3ysSjy3MRqA/f63vkD6mOntzV8/JwxIEj19xZMn0dDx7x3DnOwpk/kzYJVIz9t8jMjTAslbz\nw/MHYnh6DLJ6Rzr8fQT4afHgvAFW3y8uS2dnomdsMPJ5FtNhM7dlcE0jwpcvdFS3cUFtAI888gju\nu+8++PqaMpyWlhasX7/erQnzBKICAGsKBT9fjd2XTPAfVKVyuC/7Cz5rbBL+sdV+qUH28X9dNBgn\nf6vExz+ctTy1OHoCtAQAEYOs2k7FamwTUOfOfopaNDnNalAN05ZYu+NsG/qcNdZPGdqDd3Hz/8np\nZVm71xkjI7we11EVkNDvQqC/tkPH29x5fQaWTGPcMgeWlPeRnRaNT9bko7bGvhaC77uQEt/FaWcG\nMXrFhWL1LYMF7btkWl8cvVDh0oy4jJv7AQkKAJmZmfj2229x4YJp9aHExET4+Li20LQcXP0IxfwQ\nbDM8+++hsHM57cHP2oHvy87+sfWICUaPmGB8/IN1Bsh3HaOTEoCz64nB/sxsz2HJ/zmOs02bs8tP\nGNIDKrWKM6MXMm32/LwUfPlzEVI5MhC+j8lZI7BQHT0flRwTILrC308LrtVBPDH9gf4+GNJH+EA/\nAIiP1uHC5Vp0c8MMoGwOA4BtPX98vKl6Qq/XQ6/Xe301kEbEj8++TlBcJiV0P7VKhRmjE3kHy/Cy\nSZ9thjsuqxu2H/oDPVsbyMQEAK5MKjM5AqUV15CbzT9vvZ7VV5Hvclyfh+31hAQgf565cXwF1M/n\nDorjrG7gSgtXmtrz9NuZ16SQg6CA6UGzGPB1ULghpzd6dg2xmuLDLdd39OaAAQOgUqksxXHzF5lh\nTL01Tpw40a6Lr1q1Ctu3b0dERAS+/PLLdp3LHdhPE3/K7Y2NBfxVBbZFNXd9x1QqYPrIRADAz0dL\nePdxhKuufeGkNNyQ29tSDSNmIBhX5q3VqHHf3P4OjzM4KgE4up5N0hzN32MOzHznMw8+MiXCwUVZ\nnrx1CFZvMC1tyE729aMSsdnJGr1iKWHKFSkJeXDxpE90YEoUstOikTPAuqdWgJ9W1HQsrnIYAE6e\ntK9fltKsWbNw00034aGHHnLrdcT8wbtHBlkWsmY3HqYnOpkawSaH6dI6aZZ51kDhJQDHO3ZhT8bF\n99Ts4Pjh6bGYM4572Dq7Dl5MGwDXBYWswWA1t4vNOXrGBmP/yTLOahfbz8jPV4P1941GgJ8Gtz+3\nnfNafOlhz9E+prVxsWtEIOfatGZxrLly2GkRGgDE5OmurmWhVJ0tXvpo1fizyEkQpSRrAXPw4MEI\nDXX/aj9ifkKzx7ZljuynCWffK9trJHULwZ3Xp+PxRUNaj5emDYA9IpP3y+6wi5+/oGKymLpUVwaC\nAdaTv9mmacLgeNw7qx9u4Ojjz5U2XYCPw1ILX3rSeoQhNb4Llkzva5lm4aEbB2LBxFTnN8CRbqk5\nWsCd2BNSYhrQOgXFPCfjR5RA/OoWMgoLC4RWQJ2tLTGNcKGsft4BrNGJEU4aYzQald3Cy/ms10J6\nxQCATucHvl0HpUWjd2JbN78uITXcaVG3pcWSJhUABggM8rVLJ9eC0QGsRd75FpQ282udDoD9twkJ\nDXB6nI9P29cvKlIHnU1VTtdY7oeDmGj+aa5tme83SGc/UMmcvhfuH2uzHYiM1OHDb05Z7cclMlKH\nSI458bt0CeQ9TqvROP1szPwvta0D6+gYoefzJlz3LORziIoKxucvTO+U1WtS/507VQCorOQvljsi\nZpGTalbXMr2+rWuns2u3tBhRXs7VL8FEaFG+vr7Zbr4Ss+Zmg9U1amq5B+MZGQbl5bWIigq27G8+\n5bX6Zrt0cqWbPZmYo/sCAH1rF9gWVlfYqqprTo+71tA2avrq1Xo01Due4yI+WodLZXVOz2t1jdb7\nralptHvP0XlqrzUL2q+ysh5Mi/3Ea6b7bwtojy4YhNf/ewRVdc0wGBx/V9iuVtQ7TQf776wUfPfs\nzZ9De/7OvA8j7UmQt7OqAnLysOAsexfztCF0T94eKA7TIezc4rqB2m8TEu/Y7RlC0vX4osGWeVXc\nTejye0L/rsndQzGkTwy+3XcJ4SHCFwanKiBhFk5MtZtbijinjAAgoiGN/XNWWwUAZxFAusY687ww\nKpVrp5WiaOuj1eCGnF6Ii3K+EHjbvO5t2/wFrOF6/ahEfLvvEgBhdelqlQpqF6oAAftZIJ3x99Xi\n7pkZlukm+Ij5qKePTIRarUJetvAlCM3TBY/LEjYiWKnGDXB/jxlvJGsAWL58OQoLC1FZWYkxY8bg\n3nvvxdy5c+VMkvU0u+y+3E6Okyr/V6uAMZndcLa4GhOH9MDTH+y3vGe0meOXL6OXqmrTdsoHPuzC\nwjO3D8WxCxVIcrAcpZnVzIxuqo41/1lc+fsMSnU+ctM2cI3N6oYfD/3BOZ9ToL8W/8OaJVKIHjHB\nePneUaKWQyREKFkDwIsvvijn5Z1id4V0XgUkPIeJi9KhuLyO+02VCn6+Gs71cVts2jJ45xERnBJp\nsANR14ggdHVh9KL7BnCaPjN3dae0TffNk9IwPy9F0pWenM3MSYiraJyhnbZftNpqxkvHOZSY/OXJ\nxUNEpwqwrw/mD0odHAIkuZw0ac5vHSRna3RmV/SKC8WM0dzvu8oTl/kjRChFfFPFPPtZz7XDvZ3z\nGhI9YDq6jl0A4Mk0O7p3mzkdrnwGia1VRVKtv3znrEz8feU4u6qZQH8fPHLTIKQ7meVRrE7Yk5AQ\nC2U0ArtI3Hwu0kQAR1dpMQgtAXSs9qTj0YWDoNcbJZ3Ey9GAMKn7ftNAXdKZUQCwoeL7dzu7gQq+\nvoMLscclmPbl3k/o6NSX7x0le3WFWqWymo7B3aQOmnJ/foS0B317HVFx/pOT2CfB9J6mRSJs11t1\nxL5PePtagUOCfB0uEOKNpAoAL90zEo/fMljweAFCPJEyfv2iGgHY/xSeW4jtZXLPrExc4ugJ5LAN\noIMGQYnVmapBpFqCL1Tnh1CO6SUI6Uzo8cUGO4Ow6trp5NFRbB7o56tBr+6h9iuHOThm4mDbfvnc\nV3U075CUdeCDUqIkWevVnTpTcCKko1EAcEBU5uFqRiMwP/7LzdmYPsq6CyM7fXfPzEByN1OPGn0H\nlRTuntVP0rVeCSEdiwKALXaGzD9dvR3JBhrxPKFz1dWzrzgoNRo9YkwTPomZ/K69VE7WMJaLJ6aJ\nEE+jiADg6sLKjIgIIF0vIJ7tAi5q7pHSUSUAT2aeaC5A7NKZhCiIIgKAGFYFABG5umQFAN43OBZd\nsYkA5nUPOrIE4KmW39AfOQO7I3cg/5rEhCgdBQAbPDVAnBnz83eNQK84969oxstDSgCj+pnWGB7v\nQTMydo0Iwk0TUuHnaz3GgKqGCGlD5WMHnNXrR4T6IyE6GGeLq11uA7Dtlsg7wydX+mxea2Xqk56d\nFo3Xl43pFNUt1CuIkDZUArDFyoDZmQXvaFWV/b5iCG2f4AwAdiUA+R5vO0PmTwixpogA4GrmzJ4O\n2s9Hg9um9kFqfBerfczxQrJGYFF7W181qnU941gni5goGVUBEdKGHttssPOH6C4BmD6yJ/okmKZt\nGJHRFSMyuuLWZ7ex9jfPhClNFRBvBBCw7OLA1CgsmJiK/skRLqWFEKIsFABssJ8QGQaYMdrxXD3S\nlwBcf0RVq1ROG2LpAZgQYqaIKiB3sgQMN68HwBUYqD2TENIeFAAcENJA294qIKG4AoO7r0kI8W6K\nCABi8kkjA9wyOQ0AMFjAouCQugrI3XU0VAdECGlFbQC2GAZj+nfD6MyugmbOtNQASTYSWMwU1NJc\nkxCiTAoJAMJzSvOeQqdNVoloBMhIDHe+ghRfG4CAqSAIIUQMRQQA22yyi84XVXXNgvblkpcdb5li\nQCViINjyG7Lsttnm62JqaOKidABMgYUQQsRSRgBgZc5ZvSIxJqsb1v/nMM/Ozs8377reDq/hatoA\niIoAcVE6/G3JMESEevaiLJ4kPMT0Wck6hxMhHkIRAYAtPloHrZo/lxXbs8ZcNSNVdQxfGwBfjVQM\njfoVRRfgg1eWjlLcWsiEcFFIL6C2zJmrOshqX5HnlroROMVmqgkiveBAX2jUivjqE+KQIh6D7PJm\n1tP0M7cPQ21DCx5+62fTviIz8vZ222Qf//eV43gzJuq9SQiRmjICgG2mznod4Ke1mclSXARQS9hx\n3+FTqUTXoUBCCDFTRADwsZom2XEGL7YEkDMoDsd/q8SsMY7nDCKEEE8ja0Xojh07MHHiROTl5eGd\nd95x23VmisicxQYAXYAPHp4/0OW6+4SYYAzoHYk7r093uB89uRNCpCZbCcBgMODJJ5/EP/7xD8TE\nxGDOnDnIyclBr169JL9Wt8ggwft29OAqtVqFe2dnOt+RIgAhRGKylQAOHz6MhIQExMfHw9fXF/n5\n+SgoKHD7dZ0+4dPgWkKIQshWAigtLUVsbKzldUxMDA4f5hmc1SosLBBaLc/SjA5UNxos/w4M9EVC\nnGmBlwA/LaKigq32DQ4JsNvmCSIjdAjV+Yk+zvZegoL8PPL+pOTt98eF7lkZpL7nTtUIXFl5zbXj\nquot/752rRnBvmrcNSMDyd1CUF5ea7VvdXWD3TZPUFFRj+YG7ukr+ERFBdvdS319k0fen1S47tnb\n0T0rQ3vumS9wyBYAYmJiUFJSYnldWlqKmJgYt1/XPHJ3cBrfVM/eWQfk76tBY7OBf3F7QojiyNYG\n0K9fPxQVFeHSpUtobm7Gli1bkJOT4/brThgc7/B9b51i+eH5AzEiIxbjshwvGUkIUQ7ZSgBarRar\nV6/GbbfdBoPBgNmzZ6N3b/tJ1qSmC/Bx+L6n5v/tHQfWIyYYt03tK01iCCFeQdY2gLFjx2Ls2LFy\nJsEOLbNICFEKmhGrk6BhAIQQqVEAsOG5BQAKAYQQaVEAsEHLLBJClIICgC0Pzf8lnHSUEEIAUACw\n47lVQIQQIi0KADa0WvpICCHK0KmmgnCnxxZmY9fhPzCgd6TcSeFEVUCEEKlRAGiV1C0ESd1C5E4G\nL77F4gkhxFVU30EIIQpFAaCzoAIAIURiFAA6Ccr/CSFSowBACCEKRQGgk6BeQIQQqVEA6DQoAhBC\npKWIABDdJRAAkM27ChghhCiPIsYBBPpr8emzU1FVWe98Zw9FVUCEEKkpogQAAL4+Gst6wIQQQhQU\nAAghhFijANBJUOGFECI1CgCdBM0FRAiRGgUAQghRKAoAnQUVAAghEqMA0ElQ/k8IkRoFAEIIUSgK\nAJ0EjWEghEiNAgAhhCgUBQBCCFEoCgCEEKJQFAAIIUShKAAQQohCyRIAvvrqK+Tn5yMtLQ1HjhyR\nIwmEEKJ4sgSAlJQUvPrqqxg8eLAclyeEEAKZFoRJTk6W47KEEEJYOtWKYGFhgdBqNS4fHxUVLGFq\nOparae/M9+wqumdloHtuP7cFgFtuuQVXrlyx237//ffjuuuuc+mclZXXXE5PVFQwystrXT5ebq6k\nvbPfsyvonpWB7ln8sVzcFgDee+89d52aEEKIBKgbKCGEKJQsAeC7777DmDFjcPDgQdxxxx1YvHix\nHMkghBBFk6UROC8vD3l5eXJcmhBCSCuqAiKEEIXqVN1AlWjBxFSUVzXInQxCiBeiAODhxg/oLncS\nCCFeiqqACCFEoSgAEEKIQlEAIIQQhaIAQAghCkUBgBBCFIoCACGEKBQFAEIIUSgKAIQQolAqhmEY\nuRNBCCGk41EJgBBCFIoCACGEKBQFAEIIUSgKAIQQolAUAAghRKEoABBCiEJRACCEEIVSRADYsWMH\nJk6ciLy8PLzzzjtyJ0cSly9fxoIFCzBlyhTk5+fj/fffBwBUVVVh0aJFmDBhAhYtWoTq6mrLMW+/\n/Tby8vIwceJE7Ny5U66kt5vBYMCMGTNwxx13APD+e66pqcHSpUsxadIkTJ48GQcPHvT6e37vvfeQ\nn5+PqVOnYvny5WhqavK6e161ahWGDx+OqVOnWra5co9Hjx7FtGnTkJeXh6effhqihnYxXk6v1zO5\nubnMxYsXmaamJmbatGnMmTNn5E5Wu5WWljJHjx5lGIZhamtrmQkTJjBnzpxh1q5dy7z99tsMwzDM\n22+/zTz33HMMwzDMmTNnmGnTpjFNTU3MxYsXmdzcXEav18uW/vbYsGEDs3z5cmbJkiUMwzBef88r\nV65k/v3vfzMMwzBNTU1MdXW1V99zSUkJM378eKahoYFhGIZZunQp8+mnn3rdPRcWFjJHjx5l8vPz\nLdtcucfZs2czBw8eZIxGI7N48WJm+/btgtPg9SWAw4cPIyEhAfHx8fD19UV+fj4KCgrkTla7RUdH\nIz09HQCg0+mQlJSE0tJSFBQUYMaMGQCAGTNm4PvvvwcAFBQUID8/H76+voiPj0dCQgIOHz4sW/pd\nVVJSgu3bt2POnDmWbd58z7W1tdi3b5/lfn19fRESEuLV9wyYSnmNjY3Q6/VobGxEdHS0193z4MGD\nERoaarVN7D2WlZWhrq4OWVlZUKlUmDFjhqj8zesDQGlpKWJjYy2vY2JiUFpaKmOKpFdcXIwTJ06g\nf//+uHr1KqKjowEAUVFRuHr1KgDv+RzWrFmDBx98EGp121fXm++5uLgY4eHhWLVqFWbMmIFHH30U\n165d8+p7jomJwa233orx48dj1KhR0Ol0GDVqlFffs5nYe7TdHhsbK+revT4AeLv6+nosXboUjzzy\nCHQ6ndV7KpUKKpVKppRJ74cffkB4eDgyMjJ49/G2e9br9Th+/DjmzZuHTZs2ISAgwK4dy9vuubq6\nGgUFBSgoKMDOnTvR0NCAzZs3W+3jbffMpSPu0esDQExMDEpKSiyvS0tLERMTI2OKpNPS0oKlS5di\n2rRpmDBhAgAgIiICZWVlAICysjKEh4cD8I7P4cCBA9i2bRtycnKwfPly7NmzBytWrPDqe46NjUVs\nbCz69+8PAJg0aRKOHz/u1fe8e/duxMXFITw8HD4+PpgwYQIOHjzo1fdsJvYebbeXlJSIunevDwD9\n+vVDUVERLl26hObmZmzZsgU5OTlyJ6vdGIbBo48+iqSkJCxatMiyPScnB5s2bQIAbNq0Cbm5uZbt\nW7ZsQXNzMy5duoSioiJkZmbKknZXPfDAA9ixYwe2bduGF198EcOGDcMLL7zg1fccFRWF2NhYnD9/\nHgDw888/Izk52avvuVu3bvj111/R0NAAhmEUcc9mYu8xOjoaOp0Ohw4dAsMwVscIIlWLtifbvn07\nM2HCBCY3N5d544035E6OJPbt28ekpKQwU6dOZaZPn85Mnz6d2b59O1NRUcEsXLiQycvLY26++Wam\nsrLScswbb7zB5ObmMhMmTBDVU8AT7dmzx9ILyNvv+fjx48zMmTOZqVOnMnfddRdTVVXl9ff8yiuv\nMBMnTmTy8/OZFStWME1NTV53z8uWLWNGjhzJ9O3blxk9ejTz73//26V7PHz4MJOfn8/k5uYyTzzx\nBGM0GgWngdYDIIQQhfL6KiBCCCHcKAAQQohCUQAghBCFogBACCEKRQGAEEIUigIAISIUFxfj448/\nljsZhEiCAgAhIvz+++8UAIjXoHEAhPBoaGjAQw89hLNnz0Kr1SIxMRFnz55FcXExevbsiYSEBKxf\nvx7nz5/HmjVrUFlZiZaWFtx8882YPXs2ACA1NRV33303CgoK0NjYiOXLl2PixIky3xkhJlq5E0CI\np9q1axfq6+uxdetWAKZJyk6ePIm1a9fis88+A2CarG3FihV4/vnnkZycjLq6OsyePRtZWVlITk4G\nAKjVamzevBnnz5/HvHnzkJ2djYiICNnuixAzCgCE8EhLS8O5c+fwxBNPYMiQIRg3bpzdPkVFRTh3\n7hyWL19u2dbS0oLz589bAsDcuXMBAElJSejbty8OHTokbr4WQtyEAgAhPOLj4/Hll19iz5492LFj\nB1566SU89thjVvswDIOwsDC76YoJ6QyoEZgQHiUlJdBoNLjuuuuwatUqVFRUQKfToa6uzrJPYmIi\n/P39LTM4AsC5c+es9vn0008BmEoLx48fR1ZWVsfdBCEOUAmAEB6nTp3CunXrAABGoxFLlixBZmYm\nEhMTMXXqVCQlJWH9+vV46623sGbNGrz77rswGo2IiIjAyy+/bDmPeRH7hoYGPPnkk1T/TzwG9QIi\nxI1SU1Nx4MABBAUFyZ0UQuxQFRAhhCgUlQAIIUShqARACCEKRQGAEEIUigIAIYQoFAUAQghRKAoA\nhBCiUP8PjcdNf1eck7wAAAAASUVORK5CYII=\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3160d99240>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "pyro.clear_param_store()\n",
    "svi = pyro.infer.SVI(model=conditioned_scale, \n",
    "                     guide=scale_parametrized_guide,\n",
    "                     optim=pyro.optim.SGD({\"lr\": 0.001}),\n",
    "                     loss=\"ELBO\")\n",
    "\n",
    "losses = []\n",
    "for t in range(1000):\n",
    "    losses.append(svi.step(guess))\n",
    "    \n",
    "plt.plot(losses)\n",
    "plt.title(\"ELBO\")\n",
    "plt.xlabel(\"step\")\n",
    "plt.ylabel(\"loss\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that optimization will update the guide parameters, but does not produce a posterior distribution object itself. Once we find good parameter values, we can just use the guide as a representation of the model's approximate posterior for downstream tasks.\n",
    "\n",
    "For example, we can use the optimized guide as an importance distribution for estimating the marginal distribution over `weight` with many fewer samples than the prior:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f31602fb3c8>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\nBQAAAABJRU5ErkJggg==\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3160de3f28>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "posterior = pyro.infer.Importance(conditioned_scale, scale_parametrized_guide, num_samples=10)\n",
    "marginal = pyro.infer.Marginal(posterior, sites=[\"weight\"])\n",
    "\n",
    "plt.hist([marginal(guess)[\"weight\"].data[0] for _ in range(100)], range=(5.0, 12.0))\n",
    "plt.title(\"P(weight | measurement, guess)\")\n",
    "plt.xlabel(\"weight\")\n",
    "plt.ylabel(\"#\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also sample from the guide directly as an approximate posterior:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.text.Text at 0x7f3160236940>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<matplotlib.figure.Figure at 0x7f3160d74ef0>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "plt.hist([scale_parametrized_guide(guess).data[0] for _ in range(100)], range=(5.0, 12.0))\n",
    "plt.title(\"P(weight | measurement, guess)\")\n",
    "plt.xlabel(\"weight\")\n",
    "plt.ylabel(\"#\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Next Steps\n",
    "\n",
    "In the [Variational Autoencoder tutorial](http://pyro.ai/examples/vae.html), we'll see how models like `scale` can be augmented with deep neural networks and use stochastic variational inference to build a generative model of images."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
